﻿using Station.Inspect.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Vision.Common;
using Vision.Common.Draw;

namespace SASInspectionRY.Forms
{
    public partial class FormNodeLib : Form
    {
        List<NodeLib> nodeLibs;
        NodeLib CurLib = null;

        /// <summary>
        /// 当前操作模式
        /// </summary>
        EditMode curMode = EditMode.None;
        /// <summary>
        /// 当前捕获状态
        /// </summary>
        TrackerInfo CurTracker { get; set; }
        /// <summary>
        /// 鼠标左键按下
        /// </summary>
        bool LMouseIsDown = false;
        /// <summary>
        /// 鼠标位置
        /// </summary>
        PointF LMouseDownPos = default;
        NodeCell selectedObj;
        /// <summary>
        /// 当前选中元件
        /// </summary>
        NodeCell SelectedObj
        {
            get => selectedObj;
            set
            {
                if (selectedObj == value)
                    return;
                if (selectedObj != null)
                    selectedObj.State = TrackerState.normal;
                selectedObj = value;
                if (selectedObj != null)
                {
                    selectedObj.State = TrackerState.active;
                    tbCellID.Text = selectedObj.ID.ToString();
                }
                else
                {
                    curMode = EditMode.None;
                    tbCellID.Text = "";
                }
                    
                ucCanvas.Invalidate();
            }
        }
        NodeCell DrawRect { get; set; } = null;
        public FormNodeLib(List<NodeLib> nodeLibs)
        {
            InitializeComponent();
            this.nodeLibs = nodeLibs;
            lvNodeLib.Items.Clear();
            foreach(var item in nodeLibs)
            {
                ListViewItem listViewItem = new ListViewItem(item.Name);
                listViewItem.Tag = item;
                lvNodeLib.Items.Add(listViewItem);
            }
            if(lvNodeLib.Items.Count>0)
                lvNodeLib.Items[0].Selected = true;
        }
        private void FormNodeLib_Load(object sender, EventArgs e)
        {
            
        }

        private void lvNodeLib_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                Console.WriteLine("SelectedIndexChanged");
                CurLib = lvNodeLib.SelectedItems[0].Tag as NodeLib;
                tbID.Text = $"{CurLib.ID}";
                tbName.Text = CurLib.Name;
                cbIsMatrixPos.Checked = CurLib.IsMatrixPos;
                cbIsLablePos.Checked = CurLib.IsLablePos;
                cbIsBadMarkPos.Checked = CurLib.IsBadMarkPos;
                cbIsUseSeg.Checked = CurLib.IsUseSeg;
                tbSegThreshold.Text = CurLib.SegThreshold.ToString();
                tbSegClassThreshold.Text = CurLib.SegClassThreshold.ToString();
                tbSegMinSize.Text = CurLib.SegClassThreshold.ToString();
                tbSegMinArea.Text = CurLib.SegMinArea.ToString();
                cbIsUseSegClass.Checked = CurLib.IsUseSegClass;
                cbIsUseDefect.Checked = CurLib.IsUseDefect;
                cbIsUseDefectClass.Checked = CurLib.IsUseDefectClass;
                tbDefectThreshold.Text = CurLib.DefectThreshold.ToString();
                tbDefectClassThreshold.Text = CurLib.DefectClassThreshold.ToString();
                tbDefectMinSize.Text = CurLib.DefectMinSize.ToString();
                tbDefectMinArea.Text = CurLib.DefectMinArea.ToString();
                //--cell模板
                tbModelMinScore.Text = CurLib.ModelMinScore.ToString();
                tbModelRange.Text = CurLib.ModelRange.ToString();
                

                ucCanvas.ClearImg();
                ucCanvas.AddImg(CurLib.Image);
                ucCanvas.AutoSizeImage();
                ucCanvas.ClearDrawObject();
                foreach (var item in CurLib.NodeCells)
                    ucCanvas.AddDrawObject(item);
                ucCanvas.Invalidate();
                SelectedObj = null;
                tbWidth.Text = $"{CurLib.size.Width}";
                tbHeight.Text = $"{CurLib.size.Height}";
                tbAngle.Text = $"{CurLib.Angle}";
                tbEleNum.Text = $"{CurLib.Elements.Count}";
            }
            catch(Exception ex)
            {

            }
            
        }

        private void tbnSave_Click(object sender, EventArgs e)
        {
            if (CurLib != null)
            {
                int ID;
                float width, height, angle;
                float segThreshold, segClassThreshold,segMinSize,segMinArea;
                float defectThreshold, defectClassThreshold, defectMinSize, defectMinArea;
                float modelMinScore, modelRange;
                bool rc = true;
                rc &= int.TryParse(tbID.Text, out ID);
                rc &= float.TryParse(tbWidth.Text, out width);
                rc &= float.TryParse(tbHeight.Text, out height);
                rc &= float.TryParse(tbAngle.Text, out angle);
                rc &= float.TryParse(tbSegThreshold.Text, out segThreshold);
                rc &= float.TryParse(tbSegClassThreshold.Text, out segClassThreshold);
                rc &= float.TryParse(tbSegMinSize.Text, out segMinSize);
                rc &= float.TryParse(tbSegMinArea.Text, out segMinArea);
                rc &= float.TryParse(tbDefectThreshold.Text, out defectThreshold);
                rc &= float.TryParse(tbDefectClassThreshold.Text, out defectClassThreshold);
                rc &= float.TryParse(tbDefectMinSize.Text, out defectMinSize);
                rc &= float.TryParse(tbDefectMinArea.Text, out defectMinArea);
                rc &= float.TryParse(tbModelMinScore.Text, out modelMinScore);
                rc &= float.TryParse(tbModelRange.Text, out modelRange);
                if (rc)
                {
                    var lastItem = nodeLibs.Find(p => p.ID == ID);
                    if (lastItem == null || lastItem == CurLib)
                    {
                        int lastID = CurLib.ID;
                        CurLib.ID = ID;
                        CurLib.size = new SizeF(width, height);
                        CurLib.Angle = angle;
                        CurLib.IsMatrixPos = cbIsMatrixPos.Checked;
                        CurLib.IsLablePos = cbIsLablePos.Checked;
                        CurLib.IsBadMarkPos = cbIsBadMarkPos.Checked;
                        CurLib.IsUseSeg = cbIsUseSeg.Checked;
                        CurLib.IsUseSegClass = cbIsUseSegClass.Checked;
                        CurLib.IsUseDefect = cbIsUseDefect.Checked;
                        CurLib.IsUseDefectClass = cbIsUseDefectClass.Checked;
                        CurLib.SegThreshold = segThreshold;
                        CurLib.SegClassThreshold = segClassThreshold;
                        CurLib.SegMinSize = segMinSize;
                        CurLib.SegMinArea = segMinArea;
                        CurLib.DefectThreshold = defectThreshold;
                        CurLib.DefectClassThreshold = defectClassThreshold;
                        CurLib.DefectMinSize = defectMinSize;
                        CurLib.DefectMinArea = defectMinArea;
                        CurLib.ModelMinScore = modelMinScore;
                        CurLib.ModelRange = modelRange;
                        if (lastID != CurLib.ID)
                        {
                            lvNodeLib.SelectedItems[0].SubItems[0].Text = CurLib.Name;
                        }
                    }
                    else
                        MessageBox.Show($"已经存在ID={ID}的元件模板，请修改！");
                }
                else
                    MessageBox.Show("数据错误，请检查!");
            }
        }

        private void lvNodeLib_MouseUp(object sender, MouseEventArgs e)
        {
            Console.WriteLine("MouseUp");
            if (e.Button == MouseButtons.Right && lvNodeLib.SelectedItems.Count>0)
            {
                //cMenu.Items["tMItemDelete"].Visible = false;
                cMenu.Show(lvNodeLib, e.Location);
            }
        }

        private void cMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if(e.ClickedItem == tMItemDelete)
            {
                bool hasItem=false;
                foreach(ListViewItem item in lvNodeLib.SelectedItems)
                {
                    NodeLib lib = item.Tag as NodeLib;
                    if (lib.Elements.Count > 0)
                    {
                        hasItem = true;
                        break;
                    }
                }
                if(hasItem==false ||(hasItem && MessageBox.Show("选中的元件库中包含绑定的元件，确认删除吗？", "删除", MessageBoxButtons.YesNo) == DialogResult.Yes))
                {
                    foreach (ListViewItem item in lvNodeLib.SelectedItems)
                    {
                        NodeLib lib = item.Tag as NodeLib;
                        lib.RemoveAllElements();
                        nodeLibs.Remove(lib);
                        lvNodeLib.Items.Remove(item);
                    }
                }
            }
        }

        private void lvNodeLib_MouseDown(object sender, MouseEventArgs e)
        {
            Console.WriteLine("MouseDown");
        }

        private void lvNodeLib_MouseClick(object sender, MouseEventArgs e)
        {
            Console.WriteLine("MouseClick");
        }

        private void lvNodeLib_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            Console.WriteLine("ItemSelectionChanged");
        }
        #region 工具栏
        private void tBtnNewCell_Click(object sender, EventArgs e)
        {
            if(CurLib!=null)
            {
                curMode = EditMode.CreateElement;
            }
        }

        private void tBtnEdit_Click(object sender, EventArgs e)
        {
            if (CurLib != null)
            {
                //curMode = EditMode.CreateElement;
            }
        }

        private void tBtnDelete_Click(object sender, EventArgs e)
        {
            if (CurLib != null)
            {
                if(selectedObj != null)
                {
                    CurLib.NodeCells.Remove(selectedObj);
                    ucCanvas.RemoveDrawObject(selectedObj);
                    ucCanvas.Invalidate();
                }
            }
        }
        #endregion

        NodeCell TrySelectObj(PointF pos, float scale)
        {
            if(CurLib !=null)
            {
                foreach(var cell in CurLib.NodeCells)
                {
                    var info = cell.GetTrack(pos, scale);
                    if (info.pos != TrackerPos.tOut)
                    {
                        return cell;
                    }
                }
            }
            return null;
        }

        private void ucCanvas_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && CurLib !=null)
            {
                LMouseIsDown = true;
                LMouseDownPos = ucCanvas.CurPosInImg;
                float curScale = ucCanvas.ScaleCur;
                //TrackerInfo info = default;
                switch (curMode)
                {
                    case EditMode.CreateComponent: break;
                    case EditMode.CreateElement:
                        {
                            DrawRect = new NodeCell()
                            {
                                StartPoint = LMouseDownPos,
                                ID = CurLib.GetMaxCellID() + 1,
                                State = TrackerState.active
                            };
                            CurLib.NodeCells.Add(DrawRect);
                            ucCanvas.AddDrawObject(DrawRect);
                            break;
                        }
                    default:
                        SelectedObj = TrySelectObj(LMouseDownPos, curScale);
                        break;
                }
            }
        }

        private void ucCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            switch (curMode)
            {
                case EditMode.CreateComponent:
                case EditMode.CreateElement:
                    if (LMouseIsDown && DrawRect != null)
                    {
                        DrawRect.ReSize(ucCanvas.CurPosInImg);
                        //UpdateLBPos(DrawRect);
                    }
                    break;
                default:
                    if (SelectedObj != null)
                    {
                        if (LMouseIsDown)
                        {
                            if (CurTracker.pos == TrackerPos.tIn)
                            {
                                PointF curPt = ucCanvas.CurPosInImg;
                                selectedObj.Move(curPt.X - LMouseDownPos.X, curPt.Y - LMouseDownPos.Y);
                                LMouseDownPos = curPt;
                                //UpdateLBPos(selectedObj);
                            }
                            else if (CurTracker.pos == TrackerPos.tBorderOne || CurTracker.pos == TrackerPos.tBorderTwo)
                            {
                                if (CurTracker.para != 0 && selectedObj != null)
                                {
                                    selectedObj.ReSize(ucCanvas.CurPosInImg, CurTracker.para);
                                    //UpdateLBPos(selectedObj);
                                }
                            }
                        }
                        else
                        {
                            CurTracker = selectedObj.GetTrack(ucCanvas.CurPosInImg, ucCanvas.ScaleCur);
                            if (CurTracker.pos == TrackerPos.tIn)
                                this.Cursor = Cursors.Hand;
                            else if (CurTracker.pos == TrackerPos.tBorderOne || CurTracker.pos == TrackerPos.tBorderTwo)
                                this.Cursor = Cursors.SizeAll;
                            else
                                this.Cursor = Cursors.Default;
                        }
                    }
                    //UpdateLBPos(selectedObj);
                    break;
            }
        }

        private void ucCanvas_MouseUp(object sender, MouseEventArgs e)
        {
            LMouseIsDown = false;
            if(e.Button == MouseButtons.Left)
            {
                switch (curMode)
                {
                    case EditMode.CreateComponent:
                        curMode = EditMode.None;
                        break;
                    case EditMode.CreateElement:
                        if (DrawRect != null)
                        {
                            DrawRect = null;
                            curMode = EditMode.None;
                        }
                        break;
                    default:
                        break;
                }
            }
            else if(e.Button == MouseButtons.Right)
            {
                if(SelectedObj !=null)
                {

                }
            }
        }

        private void btnSaveCellInfo_Click(object sender, EventArgs e)
        {
            var item = SelectedObj as NodeCell;
            if(item !=null)
            {
                item.ID = int.Parse(tbCellID.Text);
            }
        }

        private void btnGuide_Click(object sender, EventArgs e)
        {
            if(CurLib !=null && CurLib.Image !=null)
            {
                FormCellGuide form = new FormCellGuide();
                if (form.ShowDialog() == DialogResult.OK)
                {
                    float dx = (CurLib.Image.Width - form.width * 2) / (float)form.cols;
                    float dy = (CurLib.Image.Height - form.height * 2) / (float)form.rows;
                    for(int i=0;i<form.rows;i++)
                    {
                        for(int j=0;j<form.cols;j++)
                        {
                            int cx = (int)(j * dx+dx/2+ form.width);
                            int cy = (int)(i * dy+dy/2+form.height);
                            var cell = new NodeCell()
                            {
                                StartPoint = new PointF(cx-dx/2-form.width,cy-dy/2-form.height),
                                Size = new SizeF(dx+ form.width*2, dy + form.height * 2),
                                ID = CurLib.GetMaxCellID() + 1,
                            };
                            ucCanvas.AddDrawObject(cell);
                            CurLib.NodeCells.Add(cell);
                        }
                    }
                }
            }
            
        }

        private void btnSetModel_Click(object sender, EventArgs e)
        {
            if (CurLib == null)
                return;
            var cell = selectedObj as NodeCell;
            if (cell ==null)
            {
                MessageBox.Show("请先选中Cell");
                return;
                
            }
            Bitmap bmp = ucCanvas.GetImage(cell.Rect, cell.angle);
            if (bmp==null)
            {
                MessageBox.Show("cell图像为空");
                return;
            }
            var hcc = new Station.Inspect.SuaModel.ModelScaledShape();
            hcc.Load(bmp);
            CurLib.IsUseMark = true;
            CurLib.ModelImage = bmp;
            CurLib.ModelMark = hcc;
        }

        private void btnDeleteModel_Click(object sender, EventArgs e)
        {
            if (CurLib == null)
                return;
            CurLib.IsUseMark = false;
            CurLib.ModelImage = null;
            CurLib.ModelMark = null;
            MessageBox.Show("已取消选中");
        }
    }
}
